#include"buildin_cmd.h"
#include"string.h"
#include"stdio.h"
#include"syscall.h"
#include"string.h"
#include"file.h"
#include"global.h"

#define E_ARGC -1
#define E_NULL 0

int32_t errorcode;
extern char cwd[];
extern char abs_path_buffer[];

static void buildin_ls(int argc,char** argv){
	int idx=1;
	bool is_verbose=false;
	char* path=NULL;
	struct stat st={0};
	struct dir* d;
	struct dir_entry* de;
	char ftch;
	char dir_path[MAX_PATH_LEN];

	if(argc>3){
		printf("<useage> ls [-l] [path]\n");
	}else{
		while(idx<argc){
			if(argv[idx][0]=='-'){
				if(!strcmp("-l",argv[idx]))
					is_verbose=true;
			}else{
				path=argv[idx];
			}
			idx++;
		}
		if(!path){
			path=".";
		}
		abs_path(abs_path_buffer,path);
		if(stat(abs_path_buffer,&st)<0){
			printf("%s invalide\n",abs_path_buffer);
			return;
		}
		if(st.ft==FT_DIR){
			d=opendir(abs_path_buffer);
			while((de=readdir(d))!=NULL){
				strcpy(dir_path,abs_path_buffer);
				if(!(abs_path_buffer[0]=='/' && abs_path_buffer[1]==0))
					strcat(dir_path,"/");
				strcat(dir_path,de->name);
				stat(dir_path,&st);
				ftch=de->ft==FT_DIR ? 'd' : '-';
				if(is_verbose){
					printf("%c    %d   %d   %s\n",ftch,de->i_no,st.i_size,de->name);
				}else{
					printf("%s ",de->name);
				}
			}
			if(!is_verbose){
				printf("\n");
			}
			closedir(d);
		}else if(st.ft==FT_NORMAL){
			char* name;
			name=strrchr(abs_path_buffer,'/')+1;
			ftch='-';
			if(is_verbose){
				printf("%c    %d    %s\n",ftch,st.i_no,name);
			}else{
				printf("%s\n",name);
			}
		}
	}
}

static void buildin_ps(void){
	ps();	
}

static void buildin_pwd(void){
	char buffer[128]={0};
	getcwd(buffer,128);
	printf("%s\n",buffer);
}

static void buildin_mkdir(int32_t argc,char** argv){
	if(argc==2){
		abs_path(abs_path_buffer,argv[1]);
		mkdir(abs_path_buffer);
	}else{
		errorcode=E_ARGC;
	}
}

static void buildin_rmdir(int32_t argc,char** argv){
	if(argc==2){
		abs_path(abs_path_buffer,argv[1]);
		rmdir(abs_path_buffer);
	}else{
		errorcode=E_ARGC;
	}
}

static void buildin_chdir(int32_t argc,char** argv){
	char* p;
	if(argc==2){
		abs_path(abs_path_buffer,argv[1]);
		if(!chdir(abs_path_buffer)){
			p=(abs_path_buffer[0]=='/' && abs_path_buffer[1]==0) ? abs_path_buffer : strrchr(abs_path_buffer,'/')+1;
			cwd[0]=0;
			strcpy(cwd,p);
		}
	}else{
		errorcode=E_ARGC;
	}
}

bool exec_buildin_cmd(int32_t argc,char** argv){
	bool is_exec=false;
	errorcode=E_NULL;
	if(!strcmp(argv[0],"ls")){
		buildin_ls(argc,argv);
		is_exec=true;
	}else if(!strcmp(argv[0],"pwd")){
		buildin_pwd();
		is_exec=true;
	}else if(!strcmp(argv[0],"cd")){
		buildin_chdir(argc,argv);
		is_exec=true;
	}else if(!strcmp(argv[0],"mkdir")){
		buildin_mkdir(argc,argv);
		is_exec=true;
	}else if(!strcmp(argv[0],"rmdir")){
		buildin_rmdir(argc,argv);
		is_exec=true;
	}else if(!strcmp(argv[0],"ps")){
		buildin_ps();
		is_exec=true;
	}
	if(errorcode<0){
		switch(errorcode){
			case E_ARGC:
				printf("argment count not valide\n");
				break;
			default:
				printf("build in command run error\n");
				break;
		}
	}
	return is_exec;
}
